package com.ly.heart.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.KingBaseCurrencyEntity;
import com.ly.heart.domain.WarehouseRegionEntity;
import com.ly.heart.domain.dto.StartProcessDto;
import com.ly.heart.domain.dto.WarehouseDto;
import com.ly.heart.domain.vo.WarehouseVo;
import com.ly.heart.service.IActModelService;
import com.ly.heart.service.IWarehouseRegionService;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import com.ly.heart.mapper.WarehouseMapper;
import com.ly.heart.domain.WarehouseEntity;
import com.ly.heart.service.IWarehouseService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

/**
 * 仓库Service业务层处理
 *
 * @author cxl
 * @date 2024-05-14
 */
@Service
public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, WarehouseEntity> implements IWarehouseService {
    @Resource
    private WarehouseMapper warehouseEntityMapper;
    @Resource
    private IWarehouseRegionService warehouseRegionService;
    @Resource
    private IActModelService actModelService;
    @Resource
    private ISysDeptService sysDeptService;

    /**
     * 查询仓库
     *
     * @param id 仓库主键
     * @return 仓库
     */
    @Override
    public WarehouseEntity selectWarehouseEntityById(String id) {
        WarehouseEntity warehouseEntity = warehouseEntityMapper.selectWarehouseEntityById(id);
        if (warehouseEntity != null) {
            List<WarehouseRegionEntity> regionEntities = warehouseRegionService.list(new LambdaQueryWrapper<WarehouseRegionEntity>()
                    .eq(WarehouseRegionEntity::getWarehouseId, id));
            warehouseEntity.setWarehouseRegionEntities(regionEntities);
        }
        return warehouseEntity;
    }

    /**
     * 查询仓库列表
     *
     * @param warehouseEntity 仓库
     * @return 仓库
     */
    @Override
    public List<WarehouseVo> selectWarehouseEntityList(WarehouseEntity warehouseEntity) {
//        warehouseEntity.setPage ( ( warehouseEntity.getPage () - 1 ) * warehouseEntity.getLimit () );
        return warehouseEntityMapper.selectWarehouseEntityList(warehouseEntity);
    }

    @Override
    public Integer queryCount(WarehouseEntity warehouseEntity) {
        return warehouseEntityMapper.queryCount(warehouseEntity);
    }

    @Override
    public IPage<WarehouseVo> selectWarehouseEntityListCopy(WarehouseDto warehouseEntity) {
        return warehouseEntityMapper.selectWarehouseEntityListCopy(warehouseEntity);
    }

    /**
     * 新增仓库
     *
     * @param warehouseEntity 仓库
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertWarehouseEntity(WarehouseEntity warehouseEntity) {
        Date nowDate = DateUtils.getNowDate();
        String id = SnowflakeIdWorker.getInstance().nextStringId();
        warehouseEntity.setId(id);
        warehouseEntity.setCreateTime(nowDate);
        StartProcessDto startDto = new StartProcessDto();
        startDto.setBusinessId(id).setBusinessType(warehouseEntity.getBusinessType()).setModelId(warehouseEntity.getModelId())
                .setBusinessName("仓库管理_".concat(id));
        String instanceId = actModelService.startProcess(startDto);
        warehouseEntity.setInstanceId(instanceId);
        warehouseEntity.setState(ConstUtil.STATE_IN_PROCESS);
        if (StringUtils.isEmpty(warehouseEntity.getWareCode())){
            int count = this.count();
            String companyId = CurrentUserUtil.getCompanyId();
            SysDept sysDept = sysDeptService.getById(companyId);
            String countStr = String.format("%06d", count);
            String firstLetter = ChineseToPinyin.getFirstLetter(sysDept.getDeptName());
            String warehouseCode = firstLetter.concat("_CKBM_").concat(countStr);
            warehouseEntity.setWareCode(warehouseCode);
        }
        boolean save = this.save(warehouseEntity);
        if (!save) {
            return AjaxResult.error("新增仓库失败");
        }
        List<WarehouseRegionEntity> regionEntities = warehouseEntity.getWarehouseRegionEntities();
        if (!CollectionUtils.isEmpty(regionEntities)) {
            regionEntities.forEach(warehouseRegion -> {
                warehouseRegion.setId(SnowflakeIdWorker.getInstance().nextStringId());
                warehouseRegion.setWarehouseId(warehouseEntity.getId());
                warehouseRegion.setCreateTime(nowDate);
            });
            boolean saved = warehouseRegionService.saveBatch(regionEntities);
            if (!saved) {
                return AjaxResult.error("新增仓位失败");
            }
        }
        return AjaxResult.success();
    }

    /**
     * 修改仓库
     *
     * @param warehouseEntity 仓库
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateWarehouseEntity(WarehouseEntity warehouseEntity) {
        Date nowDate = DateUtils.getNowDate();
        warehouseEntity.setUpdateTime(nowDate);
        List<WarehouseRegionEntity> regionEntities = warehouseEntity.getWarehouseRegionEntities();
        if (!CollectionUtils.isEmpty(regionEntities)) {
            List<WarehouseRegionEntity> list = warehouseRegionService.list(new LambdaQueryWrapper<WarehouseRegionEntity>()
                    .eq(WarehouseRegionEntity::getWarehouseId, warehouseEntity.getId()));
           //循环regionEntities判断如果有id的则更新，没有的修改，在根据list，regionEntities已有id但是在没有包含在查询结果的，则删除
            Set<String> existingIds = regionEntities.stream()
                    .filter(w -> StringUtils.isNotEmpty(w.getId()))
                    .map(warehouseRegion -> warehouseRegion.getId()).collect(Collectors.toSet());
            //过滤出list中id属性于在regionEntities不存在的
            List<WarehouseRegionEntity> toBeDeleted = list.stream()
                    .filter(entity -> !existingIds.contains(entity.getId()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(toBeDeleted)){
                List<String> removeIds = toBeDeleted.stream().map(WarehouseRegionEntity::getId).collect(Collectors.toList());
                boolean removed = warehouseRegionService.removeByIds(removeIds);
                if (!removed){
                    return AjaxResult.error("更新仓位失败");
                }
            }
            for (WarehouseRegionEntity warehouseRegion : regionEntities){
                if (warehouseRegion.getId() != null){
                    warehouseRegionService.updateById(warehouseRegion);
                }else {
                    warehouseRegion.setId(SnowflakeIdWorker.getInstance().nextStringId());
                    warehouseRegion.setWarehouseId(warehouseEntity.getId());
                    warehouseRegion.setCreateTime(nowDate);
                    warehouseRegionService.save(warehouseRegion);
                }
            }
        }
        boolean updated = this.updateById(warehouseEntity);
        if (!updated) {
            return AjaxResult.error("更新仓库失败");
        }else{
            return AjaxResult.success("更新仓库成功");
        }

    }

    /**
     * 批量删除仓库
     *
     * @param ids 需要删除的仓库主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteWarehouseEntityByIds(String[] ids) {
        // 空值检查
        if (ids == null || ids.length == 0) {
            return AjaxResult.error("ID列表不能为空");
        }
        try {
            // 删除仓库实体
            boolean removed = this.removeByIds(Arrays.asList(ids));
            if (!removed) {
                return AjaxResult.error("删除仓库失败");
            }
            // 删除相关仓位
            boolean remove = warehouseRegionService.remove(
                    new LambdaQueryWrapper<WarehouseRegionEntity>()
                            .in(WarehouseRegionEntity::getWarehouseId, ids)
            );
            if (!remove) {
                return AjaxResult.error("删除仓位失败");
            }
            return AjaxResult.success();
        } catch (Exception e) {
            // 异常处理
            log.error("删除仓库及仓位时发生异常", e);
            return AjaxResult.error("系统错误，请稍后再试");
        }
    }

    @Override
    public AjaxResult disable(String id) {
        WarehouseEntity warehouse = this.getById(id);
        if (Objects.isNull(warehouse)){
            return AjaxResult.error("仓库不存在");
        }
        boolean update = this.update ( new LambdaUpdateWrapper<WarehouseEntity>().
                set ( WarehouseEntity :: getIsDisabled, warehouse.getIsDisabled () == 1 ? 2 : 1 ).
                set ( WarehouseEntity :: getUpdateTime, DateUtils.getNowDate () ).
                set ( WarehouseEntity :: getUpdateBy, SecurityUtils.getLoginUser ().getUser ().getUserId () ).
                eq ( WarehouseEntity :: getId, id ) );
        if ( ! update ) {
            throw new CustomException( warehouse.getIsDisabled () == 1 ? "禁用仓库失败！" : "解禁仓库失败！" );
        }
        return AjaxResult.success ( warehouse.getIsDisabled () == 1 ? "禁用仓库成功" : "解禁仓库成功" );
    }

    @Override
    public IPage<WarehouseVo> selectNewWarehouseListCopy(WarehouseDto warehouse) {
        return warehouseEntityMapper.selectNewWarehouseListCopy(warehouse);
    }

    /**
     * 删除仓库信息
     *
     * @param id 仓库主键
     * @return 结果
     */
    @Override
    public int deleteWarehouseEntityById(String id) {
        return warehouseEntityMapper.deleteWarehouseEntityById(id);
    }

}
